﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Indy.Rocket.Core;
using WiimoteLib;

namespace Demo {
    public partial class MainForm : Form {
        //TODO: Show limits when reached, and disable buttons.
        Rocket mLauncher = new Rocket();
        Wiimote mWiimote;

        public MainForm() {
            InitializeComponent();
            mLauncher.Connect();
            try {
                mWiimote = new Wiimote();
                mWiimote.Connect();
                mWiimote.SetReportType(Wiimote.InputReport.ButtonsAccel, true);
                ResetRocketCount();
                timrWiimote.Enabled = true;
                lablWiimoteStatus.Text = "Wiimote is connected.";
            } catch {
                mWiimote.Dispose();
                mWiimote = null;
            }
            mLauncher.MissileFired += new MissileFiredDelegate(mLauncher_MissileFired);
        }

        void mLauncher_MissileFired(MissileFiredArgs e) {
            if (mRocketCount > 0) {
                mRocketCount--;
                UpdateLEDs();
            }
            if (mWiimote != null) {
                mWiimote.SetRumble(true);
                System.Threading.Thread.Sleep(50);
                mWiimote.SetRumble(false);
            }
        }

        private void button2_Click(object sender, EventArgs e) {
            mLauncher.MoveLeft();
        }

        private void button3_Click(object sender, EventArgs e) {
            mLauncher.StopAll();
        }

        private void button4_Click(object sender, EventArgs e) {
            mLauncher.MoveRight();
        }

        private void button5_Click(object sender, EventArgs e) {
            mLauncher.MoveUp();
        }

        private void button6_Click(object sender, EventArgs e) {
            mLauncher.MoveDown();
        }

        private void button3_Click_1(object sender, EventArgs e) {
            mLauncher.Move(Rocket.HorizDir.Left, Rocket.VertDir.Up);
        }

        private void button1_Click(object sender, EventArgs e) {
            mLauncher.Move(Rocket.HorizDir.Right, Rocket.VertDir.Up);
        }

        private void button7_Click(object sender, EventArgs e) {
            mLauncher.Move(Rocket.HorizDir.Left, Rocket.VertDir.Down);
        }

        private void button8_Click(object sender, EventArgs e) {
            mLauncher.Move(Rocket.HorizDir.Right, Rocket.VertDir.Down);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
            //Important!
            // Must stop it. If not it will keep going after our comp has shut down
            // Without safeguards will hit edges and grind gears
            // Cannot detect shutdown in Rockt class because it seems that 
            // on app shutdown GC assumes all will be killed and Finalize is not called
            mLauncher.StopAll();
        }

        private void butnFire_Click(object sender, EventArgs e) {
            mLauncher.FireOnce();
        }

        private int mRocketCount = 0;
        private void ResetRocketCount() {
            mRocketCount = 3;
            UpdateLEDs();
        }

        private void UpdateLEDs() {
            mWiimote.SetLEDs(mRocketCount > 0, mRocketCount > 1, mRocketCount > 2, false);
        }

        private void MainForm_KeyDown(object sender, KeyEventArgs e) {
            var xSpeed = e.Control ? Rocket.Speed.Slow : Rocket.Speed.Normal;
            if (e.KeyCode == Keys.NumPad5) {
                mLauncher.StopAll();
            } else if (e.KeyCode == Keys.Add) {
                mLauncher.StartFiring();
            } else if (e.KeyCode == Keys.F) {
                mLauncher.FireOnce();
            } else if (e.KeyCode == Keys.NumPad4) {
                mLauncher.MoveLeft(xSpeed);
            } else if (e.KeyCode == Keys.NumPad6) {
                mLauncher.MoveRight(xSpeed);
            } else if (e.KeyCode == Keys.NumPad8) {
                mLauncher.MoveUp(xSpeed);
            } else if (e.KeyCode == Keys.NumPad2) {
                mLauncher.MoveDown(xSpeed);
            } else if (e.KeyCode == Keys.NumPad7) {
                mLauncher.Move(Rocket.HorizDir.Left, Rocket.VertDir.Up);
            } else if (e.KeyCode == Keys.NumPad9) {
                mLauncher.Move(Rocket.HorizDir.Right, Rocket.VertDir.Up);
            } else if (e.KeyCode == Keys.NumPad1) {
                mLauncher.Move(Rocket.HorizDir.Left, Rocket.VertDir.Down);
            } else if (e.KeyCode == Keys.NumPad3) {
                mLauncher.Move(Rocket.HorizDir.Right, Rocket.VertDir.Down);
            }
        }

        Rocket.Speed mWiiSpeed = Rocket.Speed.Normal;
        bool mLastA = false;
        private void timrWiimote_Tick(object sender, EventArgs e) {
            WiimoteState xState = mWiimote.WiimoteState;
            Rocket.Speed xSpeed;
            
            if (xState.ButtonState.A != mLastA) {
                if (xState.ButtonState.A) {
                    mLauncher.StartFiring();
                } else {
                    mLauncher.StopFiring();
                }
                mLastA = xState.ButtonState.A;
            } else if (xState.ButtonState.One) {
                mLauncher.FireOnce();
            } else if (xState.ButtonState.Two) {
                ResetRocketCount();           
            }

            var xHorizDir = Rocket.HorizDir.None;
            var xVertDir = Rocket.VertDir.None;
            if (xState.ButtonState.B) {
                xSpeed = Rocket.Speed.Slow;
                if (Math.Abs(xState.AccelState.X) > 0.50
                    || Math.Abs(xState.AccelState.Y) > 0.50) {
                    xSpeed = Rocket.Speed.Normal;
                }
                if (xState.AccelState.X < -0.25) {
                    xHorizDir = Rocket.HorizDir.Left;
                } else if (xState.AccelState.X > 0.25) {
                    xHorizDir = Rocket.HorizDir.Right;
                }
                // Separate if statement so we can move diagonal too
                if (xState.AccelState.Y < -0.25) {
                    xVertDir = Rocket.VertDir.Up;
                } else if (xState.AccelState.Y > 0.25) {
                    xVertDir = Rocket.VertDir.Down;
                }
            } else {
                if (xState.ButtonState.Plus) {
                    mWiiSpeed = Rocket.Speed.Normal;
                } else if (xState.ButtonState.Minus) {
                    mWiiSpeed = Rocket.Speed.Slow;
                }
                xSpeed = mWiiSpeed;
                
                if (xState.ButtonState.Left) {
                    xHorizDir = Rocket.HorizDir.Left;
                } else if (xState.ButtonState.Right) {
                    xHorizDir = Rocket.HorizDir.Right;
                }
                // Separate if statement so we can move diagonal too
                if (xState.ButtonState.Up) {
                    xVertDir = Rocket.VertDir.Up;
                } else if (xState.ButtonState.Down) {
                    xVertDir = Rocket.VertDir.Down;
                }
            }
            mLauncher.Move(xHorizDir, xVertDir, xSpeed);

            if (xState.ButtonState.Home) {
                mLauncher.StopAll();
            }

        }

        private void MainForm_KeyUp(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.Add) {
                mLauncher.StopFiring();
            } else {
                mLauncher.StopMovements();
            }
        }

    }
}
